package cl.zeke.pizzastore.vista.managedbeans.flows.guardar_usuario;

import cl.zeke.java.commons.jsf2.Jsf2Util;
import cl.zeke.pizzastore.negocio.entities.Cliente;
import cl.zeke.pizzastore.negocio.entities.Perfil;
import cl.zeke.pizzastore.negocio.entities.Usuario;
import cl.zeke.pizzastore.negocio.exceptions.EmailExistenteException;
import cl.zeke.pizzastore.negocio.exceptions.LogicaNegocioException;
import cl.zeke.pizzastore.negocio.exceptions.RunExistenteException;
import cl.zeke.pizzastore.negocio.services.ComunesService;
import cl.zeke.pizzastore.negocio.services.UsuarioService;
import cl.zeke.pizzastore.util.ConstantesUtil;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.validator.ValidatorException;
import org.primefaces.context.RequestContext;
import org.primefaces.event.TransferEvent;
import org.primefaces.model.DualListModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

@Component
@Scope("flow")
public class GuardarUsuarioBean implements Serializable {

    private static Logger log = LoggerFactory.getLogger(GuardarUsuarioBean.class);

    //servicios (inyectados - no necesitan getters and setters)
    @Autowired
    private UsuarioService usuarioService;

    @Autowired
    private ComunesService comunesService;

    //estados del flujo (solo necesitan getters - solo lectura)
    private Boolean editar;
    private Boolean crearUsuario;
    private Boolean crearCliente;
    private Cliente clienteAux;

    //otras propiedades (necesitan getters y setters - escritura, lectura)
    private Boolean registrarCliente;
    private Usuario usuario;
    private DualListModel<Perfil> perfilPickList;
    

    public void iniciar() {
        log.debug("iniciando flujo gestionar usuarios");
        
        if (registrarCliente!= null && registrarCliente) {
            crearUsuario = false;
            editar = false;
            crearCliente = true;

            usuario = new Usuario();
            usuario.setCliente(new Cliente());
            usuario.setPerfilList(new ArrayList<Perfil>());
            usuario.getPerfilList().add(new Perfil(ConstantesUtil.ID_PERFIL_CLIENTE));

        } else if (usuario == null) {
            crearUsuario = true;
            editar = false;
            crearCliente = false;

            usuario = new Usuario();
            usuario.setPerfilList(new ArrayList<Perfil>());

        } else if (usuario != null) {
            crearUsuario = false;
            editar = true;
            crearCliente = false;
        }
        
        List<Perfil> perfilList = comunesService.traerTodosPerfiles();
        perfilList.removeAll(usuario.getPerfilList());
        perfilPickList = new DualListModel<>(perfilList, usuario.getPerfilList());
        
    }

    public void guardar() {
        
        try {
            usuario.setPerfilList(perfilPickList.getTarget());
            usuario = usuarioService.guardarUsuario(usuario);
            RequestContext.getCurrentInstance().execute("exitoDialogWV.show()");
        }catch(RunExistenteException ex) {
            Jsf2Util.addErrorMessage(":formUser:clientePanel:run", "RUN ya existe. Intente con otro");
        }catch(EmailExistenteException ex) {
            Jsf2Util.addErrorMessage(":formUser:usuarioPanel:email", "Email ya existe. Intente con otro");
        }catch(LogicaNegocioException ex) {
            Jsf2Util.addErrorMessage(ex.getMessage());
        }catch(Exception ex) {
            log.error("error", ex);
            Jsf2Util.addErrorMessage(ConstantesUtil.MSJ_ERROR_INTERNO);
        }
    }

    public void moverRoles(TransferEvent event) {
        List<Perfil> perfilList = (List<Perfil>) event.getItems();

        boolean encontrado = perfilList.contains(new Perfil(ConstantesUtil.ID_PERFIL_CLIENTE));

        if (encontrado && event.isAdd()) {
            usuario.setCliente(clienteAux!=null?clienteAux:new Cliente());
        } else if (encontrado && event.isRemove()) {
            clienteAux = usuario.getCliente();
            usuario.setCliente(null);
        }
    }
    
    //Validator JSF en Bean
    public void validarPasswordCoinciden(FacesContext context, UIComponent component, Object value) throws ValidatorException {
        log.debug("entre al validador");
        String password1 = usuario.getPassword();
        String password2 = (String) value;
        //verificar password (no en modo editar)
        if(!editar && password2 != null && password1 != null && !password1.equals(password2)) {
                throw new ValidatorException(
                        new FacesMessage(FacesMessage.SEVERITY_ERROR, "Contraseñas no coinciden", null));
        }
    }
    
    /* GET CON LOGICA */
    public String getNombreBotonGuardar() {
        return ((registrarCliente!=null&&registrarCliente)?"Registrarse":"Guardar");
    }
    
    /* GETTERS AND SETTERS */
    public Boolean getRegistrarCliente() {
        return registrarCliente;
    }

    public void setRegistrarCliente(Boolean registrarCliente) {
        this.registrarCliente = registrarCliente;
    }

    public Boolean getEditar() {
        return editar;
    }

    public Boolean getCrearUsuario() {
        return crearUsuario;
    }

    public Boolean getCrearCliente() {
        return crearCliente;
    }

    public Usuario getUsuario() {
        return usuario;
    }

    public void setUsuario(Usuario usuario) {
        this.usuario = usuario;
    }

    public DualListModel<Perfil> getPerfilPickList() {
        return perfilPickList;
    }

    public void setPerfilPickList(DualListModel<Perfil> perfilPickList) {
        this.perfilPickList = perfilPickList;
    }

}
